#include "sk_level_item.h"
#include "sk_project_item.h"
#include "sk_game_project.h"
#include "sk_creation_params.h"
#include "sk_box_shape_item.h"
#include "sk_circle_shape_item.h"
#include "sk_triangle_shape_item.h"
#include "sk_game_shape.h"
#include "sk_box_shape.h"
#include "sk_circle_shape.h"
#include "sk_triangle_shape.h"
#include "sk_game_item_proxy.h"
#include "sk_swap.h"

#include "userdata.h"
#include "mainwindow.h"
#include "sk_game_item_property.h"

#include <QPainter>

namespace sk
{

    // LEVEL ITEM
LevelItem::LevelItem(GameItem * parent, int ind)
    :
GameItem(parent, ind)
{
}

GameItemType LevelItem::type()
{
    return IT_Level;
}

int LevelItem::numChildsForProxy(int proxyInd)
{
    Q_ASSERT(proxyInd >= 0 && proxyInd <= 1);
    if (proxyInd == 0)
    {
        return level()->shapes.size();
    }
    if (proxyInd == 1)
    {
        return level()->dropShapes.size();
    }
    return 0;
}

void * LevelItem::get(GameItemType type)
{
	if (type == IT_Level)
	{
		return this;
	}
	return 0;
}

int LevelItem::numChilds()
{
    return 2;
}

GameItem * LevelItem::getChildItem(int i)
{
    Q_ASSERT(i >= 0 && i <= 1);
    if (i == 0)
    {
        GameItemProxy * res = new GameItemProxy(this, "Shapes", 0);
        res->setCanSwapChilds(true);
        res->setCanCloneChilds(true);
        return res;
    }
    if (i == 1)
    {
        GameItemProxy * res = new GameItemProxy(this, "Drop Shapes", 1);
        res->setCanSwapChilds(true);
        res->setCanCloneChilds(true);
        return res;
    }
    return 0;
}

void LevelItem::doCloneChildForProxy(int proxyInd, int ind)
{
    Q_ASSERT(proxyInd >= 0 && proxyInd <= 1);
    GameLevel * l = level();
    if (proxyInd == 0)
    {
        l->shapes.push_back(GameShapeRef(l->shapes[ind]->clone()));
    }
    else
    if (proxyInd == 1)
    {
        l->dropShapes.push_back(GameShapeRef(l->dropShapes[ind]->clone()));
    }
}

void LevelItem::doDeleteChildForProxy(int proxyInd, int childInd)
{
    Q_ASSERT(proxyInd >= 0 && proxyInd <= 1);
    GameLevel * l = level();
    if (proxyInd == 0)
    {
        l->shapes.erase(l->shapes.begin() + childInd);
    }
    else
    if (proxyInd == 1)
    {
        l->dropShapes.erase(l->dropShapes.begin() + childInd);
    }
}

void LevelItem::doSwapChildsForProxy(int proxyInd, int i, int j)
{
    Q_ASSERT(proxyInd >= 0 && proxyInd <= 1);
    GameLevel * l = level();
    if (proxyInd == 0)
    {
        l->shapes[i].swap(l->shapes[j]);
    }
    else
    if (proxyInd == 1)
    {
        l->dropShapes[i].swap(l->dropShapes[j]);
    }
}

GameItem * LevelItem::getChildItemForProxy(int proxyInd, int childInd)
{
    Q_ASSERT(proxyInd >= 0 && proxyInd <= 1);
    GameShapeRef s;
    GameLevel * l = level();
    if (proxyInd == 0)
    {
        s = l->shapes[childInd];
    }
    else
    if (proxyInd == 1)
    {
        s = l->dropShapes[childInd];
    }
    if (s->xmlType() == BoxShape::XmlType())
    {
        return new BoxShapeItem(child(proxyInd), childInd);
    }
    if (s->xmlType() == CircleShape::XmlType())
    {
        return new CircleShapeItem(child(proxyInd), childInd);
    }
    if (s->xmlType() == TriangleShape::XmlType())
    {
        return new TriangleShapeItem(child(proxyInd), childInd);
    }
    return 0;
}

GameItem * LevelItem::createItem(void * params)
{
    if (0 == params)
    {
        return 0;
    }
    SimpleItemParam * p = static_cast<SimpleItemParam*>(params);
    int ind = p->drop ? 1 : 0;
    if (p->type == IT_CLONE)
    {
        return child(ind)->cloneChild(p->ind);
    }
    else
    {
        GameLevel * l = level();
        l->addShape(p);
        return child(ind)->child(numChildsForProxy(ind) - 1);
    }
}

GameLevel * LevelItem::level()
{
    ProjectItem * pi = static_cast<ProjectItem*>(parent());
    int i = index();
    Q_ASSERT(i >= 0 && i < pi->_project->levels.size());
    return &(pi->_project->levels[index()]);
}

void LevelItem::paint(QPainter * painter, const QStyleOptionViewItem & option, int row, int column)
{
    painter->save();

    fillBg(painter, option, row, column);

    if (column == 0)
    {

        if ( (option.state & QStyle::State_MouseOver) || (option.state & QStyle::State_Selected) )
        {
            painter->setPen(Qt::white);
        }
        else
        {
            painter->setPen(Qt::black);
        }

        painter->drawText(option.rect, level()->name(), QTextOption(Qt::AlignLeft | Qt::AlignVCenter));
    }

    painter->restore();
}

bool LevelItem::canDeleteFromProjectExplorer()
{
    return true;
}

void LevelItem::onDoubleClickInProjectExplorer()
{
    _UD.mw->onLevelDoubleClicked(this);
}

int LevelItem::numProperties()
{
    return 6;
}

GameItemProperty * LevelItem::getProperty(int ind)
{
    if (0 == ind)
    {
        return new GameItemIntProperty(this, "width", &(level()->w));
    }
    if (1 == ind)
    {
        return new GameItemIntProperty(this, "height", &(level()->h));
    }
    if (2 == ind)
    {
        return new GameItemFloatProperty(this, "gravity.x", &(level()->gx));
    }
    if (3 == ind)
    {
        return new GameItemFloatProperty(this, "gravity.y", &(level()->gy));
    }
    if (4 == ind)
    {
        GameItemIntProperty * res = new GameItemIntProperty(this, "numeric", &(level()->num));
        res->bitEditor = true;
        return res;
    }
    if (5 == ind)
    {
        GameItemColorProperty * res = new GameItemColorProperty(this, "color", &(level()->color));
        return res;
    }
    Q_ASSERT(false);
    return 0;
}

} // namespace sk
